#ifndef VEC3F
#define VEC3F

#include <cmath>
#include  <base\vec2i.h>

struct vec3f {

  float x;
  float y;
  float z;

  vec3f() : x(0.0), y(0.0), z(0.0) {
  }

  vec3f(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {
  }

  vec3f(const vec3f &b) : x(b.x), y(b.y), z(b.z) {
  }

  vec3f operator-(vec3f b) {
    return vec3f(x - b.x, y - b.y, z - b.z);
  }

  vec3f operator+(vec3f b) {
    return vec3f(x + b.x, y + b.y, z + b.z);
  }

  vec3f operator*(float value) const {
    return vec3f(x * value, y * value, z * value);
  }

  vec3f operator*(vec3f b) const {
    return vec3f(x * b.x, y * b.y, z * b.z);
  }

  vec3f operator/(float value) const {
    return vec3f(x / value, y / value, z / value);
  }

  vec3f operator/(vec3f b) const {
    return vec3f(x / b.x, y / b.y, z / b.z);
  }

  float &operator[](int index) {
    if (index == 0) return x;
    else if (index == 1) return y;
    else return z;
  }

  bool operator==(vec3f b) {
    return (x == b.x && y == b.y && z == b.z);
  }

  bool operator!=(vec3f b) {
    return !(x == b.x && y == b.y && z == b.z);
  }

  vec3f operator - (void) const { 
    return vec3f(-x, -y, -z); 
  }

  float dot(const vec3f & v) const { 
    return x * v.x + y * v.y + z * v.z; 
  }

  vec3f cross(const vec3f & v) const {
    return vec3f(y*v.z - z*v.y,
                 z*v.x - x*v.z,
                 x*v.y - y*v.x);
  }

  vec2i to2d() {
    return vec2i((int) x, (int) y);
  }

  vec2i to2dr() {
    return vec2i(ROUND(x), ROUND(y));
  }


  float length() {
    return((float)sqrt(x*x + y*y + z*z));
  }

  void normalize() {
    float len;
    len = length();
	  if (len) {
		  x /= len;
		  y /= len;
		  z /= len;
	  }
  }

  float innerProduct(vec3f v) {
    return (x * v.x + y * v.y + z * v.z);
  }

};

#endif